/*
XPTracker - Alternative Agile Tracking Tool
Copyright (C) 2006-2009  Stephen Starkey

This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
*/
package org.xptracker.web;

import com.google.inject.Inject;
import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.collections.Factory;
import org.apache.commons.collections.map.LazyMap;
import org.xptracker.domain.*;
import org.xptracker.util.ThreadLocalCleaner;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class WebUtil {
  private static final ThreadLocal<DateFormat> FMT = ThreadLocalCleaner.registerForCleanup(new ThreadLocal<DateFormat>() {
    protected DateFormat initialValue() {
      return new SimpleDateFormat("yyyy-MM-dd");
    }
  });

  @SuppressWarnings({"unchecked"})
  private static final Map<Class, PropertyRenderer> RENDERERS = 
      LazyMap.decorate(new HashMap<Class, PropertyRenderer>() {{
        final PropertyRenderer<Date> DATE_RENDERER = new PropertyRenderer<Date>() {
          public String renderProperty(Date property) {
            return FMT.get().format(property);
          }
        };

        put(Date.class, DATE_RENDERER);
        put(Timestamp.class, DATE_RENDERER);
        put(java.sql.Date.class, DATE_RENDERER);

        put(User.class, new PropertyRenderer<User>() {
          public String renderProperty(User property) {
            return property.getUsername();
          }
        });
  }}, new Factory() {
    public Object create() {
      return PropertyRenderer.DEFAULT;
    }
  });

  @Inject
  public static Domain domain;

  public static List<Story> getStories(Queue queue) {
    return new QueueSource(queue).getStories(domain);
  }

  public static String displayProperty(Object o, String property) throws Exception {
    Object result = PropertyUtils.getProperty(o, property);
    if (result == null) {
      return "<null>";
    }
    return RENDERERS.get(result.getClass()).renderProperty(result);
  }

  private static interface PropertyRenderer<T> {
    PropertyRenderer<Object> DEFAULT = new PropertyRenderer<Object>() {
      public String renderProperty(Object property) {
        return String.valueOf(property);
      }
    };

    String renderProperty(T property);
  }

  public static boolean isFit(WikiContent content) {
    return content != null && content.getWikiStyle().equals(WikiStyle.fitnesse);
  }
}
